#pragma once
#include <iostream>
#include <string>
#include <unistd.h>

using namespace std;

#define SPACE " " // 空格
#define LINEFEED "\n"   //回车换行


enum{

};

//添加报头,使其变为请求
//将"x op y"  变为  "len"/n"x op y"/n
//报头为正文部分的字符串长度
string AddMasthead(string& content)
{
	//请求
	string send_beg=to_string(content.size());
	send_beg+=LINEFEED;
	send_beg+=content;
	send_beg+=LINEFEED;

	return send_beg;
} 

//删除报头
//将  "len"\n"x op y"\n 转化为 "x op y"
//将请求传入，将正文传回
bool DeleteMasthead(string& package,string& content)
{
	//找到 "\n" 的位置
	auto pos=package.find(LINEFEED);
	if(pos==string::npos)//找不到，则返回错误
	return false;

	//截取报头字符串,并将其变为整数
	string len_string=package.substr(0,pos);
	size_t len=stoi(len_string);

	//判断报文是否完整
	size_t total_len = len_string.size() + len + 2;
    if(package.size() < total_len) return false;

	//截取正文字符串
	content=package.substr(pos+1,len);

	//移除报文
	package.erase(0, total_len);

	return true;
}



class Request
{
public:
	// 构造函数
	Request(int x = 0, int y = 0, char op = 0)
		: _x(x), _y(y), _op(op)
	{
	}

	// Request序列化
	// Request结构体转化为字符串"a op b"
	bool Serialization(string &out)
	{
		// 将里面的数据清空
		out.clear();

		// 将数字转化为字符串类型
		string x_string = to_string(_x);
		string y_string = to_string(_y);

		// 将out字符串里变为"x op y"
		out = x_string;
		out += SPACE;
		out += _op;
		out += SPACE;
		out += y_string;

		return true;
	}

	// Request反序列化
	// 字符串"x op y"转化为Request结构体
	bool desocialization(string &in)
	{

		// 找到两个空格的下标
		size_t leftspace = in.find(SPACE);
		size_t rightspace = in.rfind(SPACE);

		// 如果相等，说明找到了最后都没有找到，返回错误
		if (leftspace == string::npos)
			return false;
		if (rightspace == string::npos)
			return false;

		// 如果相等，则空格只有一个，字符串错误
		if (leftspace == rightspace)
			return false;

		// 如果leftspace+1和rightspace-1，不指向同一个op，则字符串错误
		if ((leftspace + 1) != (rightspace - 1))
			return false;

		// 使用左闭右开的方式读取字符串[),从当前位置，读取几个字符
		string x_string = in.substr(0, leftspace);		// 将字符串"x"，存入x_string中
		string y_string = in.substr(rightspace + 1, 1); // 将字符串"y"，存入x_string中

		// 读取到的数字不能为空
		if (x_string.empty() || y_string.empty())
			return false;

		//填入数据
		_x=stoi(x_string);
		_y=stoi(y_string);
		_op=in[leftspace+1];

		return true;
	}

	void PrintData()
	{
		cout << "新请求构建完成:  " << _x << _op << _y << "=?" << std::endl;
	}

public:
	int _x;	  // 参数x
	int _y;	  // 参数y
	char _op; // 运算符
};

class Response
{
public:
	// 构造函数
	Response(int result = 0, int exitcode = 0)
		: _result(result), _exitcode(exitcode)
	{
	}

	// Response序列化
	// Response结构体转化为字符串"result exitcode"
	bool Serialization(string &out)
	{
		// 将里面的数据清空
		out.clear();

		// 将数字转化为字符串类型
		string result_string = to_string(_result);
		string exit_string = to_string(_exitcode);

		// 将out字符串里变为"result exitcode"
		out = result_string;
		out += SPACE;
		out += exit_string;

		return true;
	}

	// Response反序列化
	// 字符串"result exitcode"转化为Response结构体
	bool desocialization(string &out)
	{
		// 找到空格的下标
		size_t leftspace = out.find(SPACE);
        size_t rightspace = out.rfind(SPACE);

		//如果leftspace不等于rightspace，则说明字符串有问题
		if(leftspace!=rightspace)
		return false;
		//如果找不到空格，则返回错误
		if((leftspace==string::npos)||(rightspace==string::npos))
		return false;

		// 使用左闭右开的方式读取字符串[),从当前位置，读取几个字符
		string result_string = out.substr(0, leftspace);		// 将字符串"x"，存入x_string中
		string exit_string = out.substr(rightspace + 1, 1); // 将字符串"y"，存入x_string中

		// 读取到的数字不能为空
		if (result_string.empty() || exit_string.empty())
			return false;

		//填入数据
		_result=stoi(result_string);
		_exitcode=stoi(exit_string);

		return true;
	}

	void PrintfData()
	{
		cout << "结果响应完成, result: " << _result << ", exitcode: "<< _exitcode << std::endl;
	}

public:
	int _result;   // 计算结果
	int _exitcode; // 错误码
};